package util;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.imageio.ImageIO;

import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.opencv_core.Mat;

import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;
import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDManager;
import ai.djl.ndarray.types.DataType;
import net.coobird.thumbnailator.Thumbnails;



/**
 * 数据类型转换
 * @author ShiQiang
 *
 */
public class ConverterImg{
	/**
	 * 将mat转BufferedImage
	 * @param matrix 
	 */
	public static BufferedImage m2B(Mat matrix) { 
		int cols=matrix.cols();
		int rows=matrix.rows();
		int elemSize=(int)matrix.elemSize();
		byte[] data=new byte[cols*rows*elemSize];
		
		matrix.data().get(data); 
		
		int type = 0; 
		switch(matrix.channels()){
		case 1:
			type=BufferedImage.TYPE_BYTE_GRAY;
			break;
		case 3:
			type=BufferedImage.TYPE_3BYTE_BGR;
			byte b;
			for(int i=0;i<data.length;i=i+3){
				b=data[i];
				data[i]=data[i+2];
				data[i+2]=b;
			}
			break;
		default:
			return null; 
		}
		BufferedImage image=new BufferedImage(cols,rows,type);
		image.getRaster().setDataElements(0, 0,cols,rows,data);
		return image;
	} 

    /**
     * 将bufferImage转Mat
     * @param original	
     * @param imgType
     * @param matType
     * @param msg
     * @param x
     * @param y 
     */
  /* public static Mat b2M(BufferedImage original,int matType,String msg,int x,int y) {
        Graphics2D g = original.createGraphics(); 
        try {
            g.setComposite(AlphaComposite.Src);
            g.drawImage(original, 0, 0, null);
            g.drawString(msg, x, y);
        } finally {
            g.dispose();
        } 
        Mat mat = new Mat(original.getHeight(), original.getWidth(), matType); 
        mat.data().put(((DataBufferByte) original.getRaster().getDataBuffer()).getData()); 
        return mat;
    } */
   public static Mat b2M2(BufferedImage original,int matType) {
	   original = convert(original,BufferedImage.TYPE_3BYTE_BGR);
       Mat mat = new Mat(original.getHeight(), original.getWidth(), matType); 
       mat.data().put(((DataBufferByte) original.getRaster().getDataBuffer()).getData()); 
       return mat;
   } 
    public static Mat b2M(BufferedImage original,int matType) { 
    	Mat mat = new Mat(original.getHeight(), original.getWidth(), matType);  
    	byte[] ibyte = null;	 
        if(original.getType()!=BufferedImage.TYPE_3BYTE_BGR){
            // 转sRGB格式
            BufferedImage rgbImage = new BufferedImage(
            		original.getWidth(), 
            		original.getHeight(),  
                        BufferedImage.TYPE_3BYTE_BGR);
            new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null).filter(original, rgbImage);
            // 从Raster对象中获取字节数组
            ibyte = (byte[]) rgbImage.getData().getDataElements(0, 0, rgbImage.getWidth(), rgbImage.getHeight(), null);
        }else{
        	ibyte = (byte[]) original.getData().getDataElements(0, 0, original.getWidth(), original.getHeight(), null);
        }
		mat.data().put(ibyte);
        return mat;
    } 
    public static byte[] getMatrixBGR(BufferedImage image){
        
        byte[] matrixBGR;
        if(image.getType()!=BufferedImage.TYPE_3BYTE_BGR){
        	 BufferedImage rgbImage = new BufferedImage(
        			 image.getWidth(), 
        			 image.getHeight(),  
                         BufferedImage.TYPE_3BYTE_BGR);
             new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null).filter(image, rgbImage);
            matrixBGR= (byte[]) rgbImage.getData().getDataElements(0, 0, rgbImage.getWidth(), rgbImage.getHeight(), null);
        }else{          
            // ARGB格式图像数据
            int intrgb[]=image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());
            matrixBGR=new byte[image.getWidth() * image.getHeight()*3];
            // ARGB转BGR格式
            for(int i=0,j=0;i<intrgb.length;++i,j+=3){
                matrixBGR[j]=(byte) (intrgb[i]&0xff);
                matrixBGR[j+1]=(byte) ((intrgb[i]>>8)&0xff);
                matrixBGR[j+2]=(byte) ((intrgb[i]>>16)&0xff);
            }
        } 
        return matrixBGR;
    }
    public static BufferedImage convert(BufferedImage src, int bufImgType) {
        BufferedImage img= new BufferedImage(src.getWidth(), src.getHeight(), bufImgType);
        Graphics2D g2d= img.createGraphics();
        g2d.drawImage(src, 0, 0, null);
        g2d.dispose();
        return img;
    }
    public static Mat b2M(ByteArrayOutputStream out,int w,int h) { 
    	Mat mat = new Mat(h, w, opencv_core.CV_8UC1); 
    	mat.data().put(out.toByteArray());
        return mat;
    } 
    public static void main(String[] args) throws IOException {
    	 Mat mat = new Mat();
    	 Path imageFile = Paths.get("src/main/resources/img/2m.jpg"); 
         Image image = ImageFactory.getInstance().fromFile(imageFile); 
         NDManager manager = NDManager.newBaseManager();
         NDArray img = image.toNDArray(manager).toType(DataType.UINT8, true); 
         //Thumbnails.of((BufferedImage)ImageFactory.getInstance().fromNDArray(img).getWrappedImage()).scale(1).outputFormat("png").toFile("F:/1/face"+ File.separator +  "FACE.jpg");
         //ByteArrayOutputStream out = new ByteArrayOutputStream();
         BufferedImage tmpImg = (BufferedImage)ImageFactory.getInstance().fromNDArray(img).getWrappedImage();
        
         //Thumbnails.of(tmpImg).scale(1).outputFormat("png").toOutputStream(out);
         //Thumbnails.of(tmpImg).scale(1).outputFormat("png").toFile("F:/1/face"+ File.separator +  "FACE.jpg");
         
         //Mat m= b2M(tmpImg,opencv_core.CV_8UC3);
         Mat m= b2M2(tmpImg,opencv_core.CV_8UC3);
         
         opencv_imgcodecs.imwrite("F:/1/face"+ File.separator +  "FACE.jpg", m);
         manager.close();
	}
}